// ==UserScript==
// @name           grill-spy
// @namespace      org.codegrill.ikariam
// @description    Displays spy defense information of a colony
//
//                 Author: brains
//                 Server: Theta
//                 Email: bwdenton@gmail.com
//                 Copyright 2009 Brian Denton
//
//                 This program is free software: you can redistribute it and/or modify
//                 it under the terms of the GNU General Public License as published by
//                 the Free Software Foundation, either version 3 of the License, or
//                 (at your option) any later version.
//
//                 This program is distributed in the hope that it will be useful,
//                 but WITHOUT ANY WARRANTY; without even the implied warranty of
//                 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//                 GNU General Public License for more details <http://www.gnu.org/licenses/>.
//
// @include        http://*.ikariam.*
// @exclude        http://board.ikariam.*
// @require        http://ikariam-grill.googlecode.com/svn/tags/grill-debug/1.0/grill-debug.user.js
// @require        http://ikariam-grill.googlecode.com/svn/tags/grill-sdk/0.2/grill-sdk.user.js
// ==/UserScript==

const DIV_SCORE_HIGH = "ikariam-spy-score-high";
const DIV_PLACE_HIGH = "ikariam-spy-place-high";
const DIV_SCORE_GENERALS = "ikariam-spy-score-generals";
const DIV_PLACE_GENERALS = "ikariam-spy-place-generals";
const DIV_SCORE_GOLD = "ikariam-spy-score-gold";
const DIV_PLACE_GOLD = "ikariam-spy-place-gold";

const DIV_SPY_DEFENSE = "ikariam-spy-defense";
const DIV_SPY_SPIES = "ikariam-spy-spies";
const DIV_SPY_CAP = "ikariam-spy-cap";

const CACHE_SPY_SCORE_TIMEOUT = "score.timeout";
const CACHE_SPY_SCORE_CHECKED = "score.checked";
const SPY_SCORE_TIMEOUT = 180000; //3 minutes

const CACHE_SPY_SCORE_HIGH = "score.high";
const CACHE_SPY_SCORE_GENERALS = "score.generals";
const CACHE_SPY_SCORE_GOLD = "score.gold";

const CACHE_SPY_PLACE_HIGH = "place.high";
const CACHE_SPY_PLACE_GENERALS = "place.generals";
const CACHE_SPY_PLACE_GOLD = "place.gold";

(function () {
    try {
        grill_init(); //Cache all data on the current page
        grill_spy_init();

        //Find the correct element on the page to insert spy grill information
        var elementId = grill_spy_getInsertElementId();

        if (elementId) {
            if (grill_dom_insertAfterId(grill_spy_createSpyDiv(), elementId)) {
                var server = grill_getServer();

                grill_spy_updateSpies();
                grill_spy_updateScores(server, grill_getPlayer(grill_cache_getPlayer(server)));
            }
        }
    }
    catch (e) { GM_log(e); }
})();

function grill_spy_init() {
    var server = grill_getServer();
    var player = grill_getPlayer(grill_cache_getPlayer(server));

    grill_cache_setPlayerProp(server, player, CACHE_SPY_SCORE_TIMEOUT ,SPY_SCORE_TIMEOUT);
    grill_spy_setOnClickIslandHandler();
}

function grill_spy_getScoreTimeout() {
    var server = grill_getServer();
    var player = grill_getPlayer(grill_cache_getPlayer(server));

    return grill_cache_getPlayerProp(server, player, CACHE_SPY_SCORE_TIMEOUT);
}

function grill_spy_getScoreChecked(server, player) {
    var checked = grill_cache_getPlayerProp(server, player, CACHE_SPY_SCORE_CHECKED);

    if (checked) {
        return parseFloat(checked);
    }

    return null;
}

function grill_spy_setScoreChecked(server, player) {
    grill_cache_setPlayerProp(server, player, CACHE_SPY_SCORE_CHECKED, (new Date()).getTime().toString());
}

/////////////////////////////////////////////////////////////////////
// Ikariam Spy UI Functions
/////////////////////////////////////////////////////////////////////
function grill_spy_getInsertElementId() {
    var elementId = null;

    switch(grill_getView()) {
        case VIEW_ISLAND:
            elementId = "infocontainer";
            break;
        case VIEW_COLONY:
            elementId = "information";
            break;
        case BUILDING_TYPE_HIDEOUT:
            elementId = "buildingUpgrade";
            break;
        default:
            break;
     };

    return elementId;
}

function grill_spy_parseScore(text) {
    var score = {};

    if (text) {
        //We've got to append this as a hidden element to the page so we can use DOM to parse
        var div = document.createElement("div");
        div.setAttribute("style", "display: none;");
        div.setAttribute("id", "grill-spy-hidden");
        document.body.appendChild(div);

        div.innerHTML = text;

        //Get the score
        var node = grill_xpath_getFirstNode("//div[@id='grill-spy-hidden']//td[@class='" + CLASS_SCORE + "']");

        if (node && node.innerHTML) {
            score["score"] = grill_trim(node.innerHTML);
        }
        else {
            GM_log("grill_spy_parseScore(text): could not find the score element");
        }

        //Get the place
        node = grill_xpath_getFirstNode("//div[@id='grill-spy-hidden']//td[@class='" + CLASS_PLACE + "']");

        if (node && node.innerHTML) {
            score["place"] = grill_trim(node.innerHTML);
        }
        else {
            GM_log("grill_spy_parseScore(text): could not find the place element");
        }

        //Get the alliance
        node = grill_xpath_getFirstNode("//div[@id='grill-spy-hidden']//td[@class='" + CLASS_ALLY + "']/a");

        if (node && node.innerHTML) {
            score["ally"] = grill_trim(node.innerHTML);
        }

        //Get the player
        node = grill_xpath_getFirstNode("//div[@id='grill-spy-hidden']//td[@class='" + CLASS_PLAYER + "']");

        if (node && node.innerHTML) {
            score["player"] = grill_trim(node.innerHTML);
        }
        else {
            GM_log("grill_spy_parseScore(text): could not find the player element");
        }

        //Remove the hidden div
        document.body.removeChild(div);
    }
    else {
        GM_log("grill_spy_parseScore(text): text is null");
    }

    return score;
}

function grill_spy_setOnClickIslandHandler() {
    var cities = document.getElementById("cities");
    if (cities) {
        var anchors = cities.getElementsByTagName("a");

        if (anchors) {
            for each (var a in anchors) {
                if (a.id && a.id.substring(0, 5) == "city_") {
                    a.addEventListener('click', function() { window.setTimeout(grill_spy_onUpdateScores, 1); }, false);
                }
            }
        }
    }
}

function grill_spy_getOwner() {
    var xpath = "//div[@id='information']/ul/li[@class='owner']";
    var node = grill_xpath_getFirstNode(xpath);
    var owner = null;

    if (node && node.childNodes && node.childNodes.length > 1) {
        owner = grill_trim(node.childNodes[1].nodeValue);
    }

    return owner;
}

function grill_spy_onUpdateScores() {
    var server = grill_getServer();
    var player = grill_spy_getOwner();

    grill_spy_updateScores(server, player);
}

function grill_spy_updateScores(server, player) {
    if (grill_spy_needsScoreUpdate(server, player)) {
        grill_spy_setScoreChecked(server, player);

        grill_dom_updateId(DIV_SCORE_HIGH, "...");
        grill_dom_updateId(DIV_PLACE_HIGH, "...");
        grill_dom_updateId(DIV_SCORE_GENERALS, "...");
        grill_dom_updateId(DIV_PLACE_GENERALS, "...");
        grill_dom_updateId(DIV_SCORE_GOLD, "...");
        grill_dom_updateId(DIV_PLACE_GOLD, "...");

        grill_http_getScore(player, URL_REQUEST_HIGHSCORE, grill_spy_updateHighscore);
        grill_http_getScore(player, URL_REQUEST_GENERALS, grill_spy_updateGenerals);
        grill_http_getScore(player, URL_REQUEST_GOLD, grill_spy_updateGold);
    }
    else {
        grill_dom_updateId(DIV_SCORE_HIGH, grill_cache_getPlayerProp(server, player, CACHE_SPY_SCORE_HIGH));
        grill_dom_updateId(DIV_PLACE_HIGH, grill_cache_getPlayerProp(server, player, CACHE_SPY_PLACE_HIGH));
        grill_dom_updateId(DIV_SCORE_GENERALS, grill_cache_getPlayerProp(server, player, CACHE_SPY_SCORE_GENERALS));
        grill_dom_updateId(DIV_PLACE_GENERALS, grill_cache_getPlayerProp(server, player, CACHE_SPY_PLACE_GENERALS));
        grill_dom_updateId(DIV_SCORE_GOLD, grill_cache_getPlayerProp(server, player, CACHE_SPY_SCORE_GOLD));
        grill_dom_updateId(DIV_PLACE_GOLD, grill_cache_getPlayerProp(server, player, CACHE_SPY_PLACE_GOLD));
    }
}

function grill_spy_needsScoreUpdate(server, player) {
    var checked = grill_spy_getScoreChecked(server, player);

    if (checked) {
        return (new Date()).getTime() - checked > grill_spy_getScoreTimeout();
    }

    return true;
}

function grill_spy_updateHighscore(response) {
    var score = grill_spy_parseScore(response.responseText)
    grill_dom_updateId(DIV_SCORE_HIGH, score["score"]);
    grill_dom_updateId(DIV_PLACE_HIGH, "(" + score["place"] + ")");

    //Cache these values
    grill_cache_setPlayerProp(grill_getServer(), score["player"], CACHE_SPY_SCORE_HIGH, score["score"]);
    grill_cache_setPlayerProp(grill_getServer(), score["player"], CACHE_SPY_PLACE_HIGH, "(" + score["place"] + ")");
}

function grill_spy_updateGenerals(response) {
    var score = grill_spy_parseScore(response.responseText)
    grill_dom_updateId(DIV_SCORE_GENERALS, score["score"]);
    grill_dom_updateId(DIV_PLACE_GENERALS, "(" + score["place"] + ")");

    //Cache these values
    grill_cache_setPlayerProp(grill_getServer(), score["player"], CACHE_SPY_SCORE_GENERALS, score["score"]);
    grill_cache_setPlayerProp(grill_getServer(), score["player"], CACHE_SPY_PLACE_GENERALS, "(" + score["place"] + ")");
}

function grill_spy_updateGold(response) {
    var score = grill_spy_parseScore(response.responseText)
    grill_dom_updateId(DIV_SCORE_GOLD, score["score"]);
    grill_dom_updateId(DIV_PLACE_GOLD, "(" + score["place"] + ")");

    //Cache these values
    grill_cache_setPlayerProp(grill_getServer(), score["player"], CACHE_SPY_SCORE_GOLD, score["score"]);
    grill_cache_setPlayerProp(grill_getServer(), score["player"], CACHE_SPY_PLACE_GOLD, "(" + score["place"] + ")");
}

function grill_spy_updateSpies() {
    var colony = grill_getCurrentColony();
    var building = colony.buildings[BUILDING_TYPE_HIDEOUT];
    var spies = grill_getSpies(grill_cache_getSpies(colony.server, colony.player, colony.id));
    var trained = grill_getTrainedSpies(grill_cache_getTrainedSpies(colony.server, colony.player, colony.id));
    var level = 0;

    if (building) {
        if (!spies) { spies = building.level; }
        if (!trained) { trained = building.level; }
        level = building.level;
    }
    else {
        spies = 0;
        trained = 0;
    }

    var defense = grill_spy_getSpyDefense(colony.level, level, spies, level);
    var cap = grill_spy_getEnemyCap(colony.level, level, spies);
    if (cap < 0) { cap = 0; }
    if (defense < 5) { defense = 5; }

    grill_dom_updateId(DIV_SPY_DEFENSE, defense + "%");
    grill_dom_updateId(DIV_SPY_SPIES, "(" + spies + "/" + trained + ")");
    grill_dom_updateId(DIV_SPY_CAP, "L" + cap + " enemy hideout");
}

/**
 * Create the div to be inserted
 */
function grill_spy_createSpyDiv() {
            var xml = <>
            <h3 class="header">Spy Grill</h3>
            <div class="content">
                <ul style="text-align: left" class="cityinfo">
                    <li style="margin: 2px 10px;" class="name">
                        <span style="float:left;text-align:left;width:80px;" class="textLabel">Highscore: </span>
                        <span style="float:left;text-align:left;width:80px;" id="DIV_SCORE_HIGH">...</span>
                        <span id="DIV_PLACE_HIGH">...</span>
                    </li>
                    <li style="margin: 2px 10px;" class="name">
                        <span style="float:left;text-align:left;width:80px;" class="textLabel">Generals: </span>
                        <span style="float:left;text-align:left;width:80px;" id="DIV_SCORE_GENERALS">...</span>
                        <span id="DIV_PLACE_GENERALS">...</span>
                    </li>
                    <li style="margin: 2px 10px;" class="name">
                        <span style="float: left;text-align:left;width:80px;" class="textLabel">Gold: </span>
                        <span  style="float:left;text-align:left;width:80px;" id="DIV_SCORE_GOLD">...</span>
                        <span id="DIV_PLACE_GOLD">...</span>
                    </li>
                </ul>
                <hr style="background-color:#CDA55F;border:0;height:1px;width:90%;"/>
                <ul style="text-align: left" class="cityinfo">
                    <li style="margin: 2px 10px;" class="name">
                        <span style="float:left;text-align:left;width:80px;" class="textLabel">Spy Defense: </span>
                        <span style="float:left;text-align:left;width:80px;" id="DIV_SPY_DEFENSE">...</span>
                        <span id="DIV_SPY_SPIES">...</span>
                    </li>
                    <li style="margin: 2px 10px;" class="name">
                        <span style="float: left;text-align:left;width:80px;" class="textLabel">Spy Cap: </span>
                        <span id="DIV_SPY_CAP"></span>
                    </li>
                </ul>
            </div>
            <div class="footer" />
            </>; //An XMLList object

            xmlString = xml.toXMLString();
            xmlString = xmlString.replace("DIV_SCORE_HIGH", DIV_SCORE_HIGH);
            xmlString = xmlString.replace("DIV_SCORE_GENERALS", DIV_SCORE_GENERALS);
            xmlString = xmlString.replace("DIV_SCORE_GOLD", DIV_SCORE_GOLD);

            xmlString = xmlString.replace("DIV_PLACE_HIGH", DIV_PLACE_HIGH);
            xmlString = xmlString.replace("DIV_PLACE_GENERALS", DIV_PLACE_GENERALS);
            xmlString = xmlString.replace("DIV_PLACE_GOLD", DIV_PLACE_GOLD);

            xmlString = xmlString.replace("DIV_SPY_DEFENSE", DIV_SPY_DEFENSE);
            xmlString = xmlString.replace("DIV_SPY_SPIES", DIV_SPY_SPIES);
            xmlString = xmlString.replace("DIV_SPY_CAP", DIV_SPY_CAP);

            var div = document.createElement("div");
            div.setAttribute("class", "dynamic");
            div.setAttribute("id", "grillSpy");
            div.innerHTML = xmlString;

            return div;
}